package com.weds.data_sync.config;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @Description 线程池配置
 * @Author lihw
 * @Date 2024/1/9 9:57
 */
@Slf4j
@Component
@Data
public class ThreadPoolConfig {
    /**
     * 获取CPU核数
     */
    private static final int CPU_NUM;

    /**
     * 配置线程池的前缀
     */
    @Value("${thread.pool.executor.threadNamePrefix}")
    private String threadNamePrefix = "threadPoolTaskExecutor-";

    /**
     * 线程池的核心线程数。在没有设置 allowCoreThreadTimeOut 为 true 的情况下，
     * 核心线程会在线程池中一直存活，即使处于闲置状态。
     */
    private Integer corePoolSize;

    /**
     * 线程池中的任务队列，通过线程池的 execute() 方法提交的 Runnable
     * 对象会存储在该队列中。
     */
    @Value("${thread.pool.executor.queueCapacity}")
    private Integer queueCapacity = 1000;

    /**
     * 线程池所能容纳的最大线程数。当活动线程(核心线程+非核心线程)达到这个数值后，
     * 后续任务将会根据 RejectedExecutionHandler 来进行拒绝策略处理。
     */
    private Integer maxPoolSize;

    /**
     * 当任务无法被执行时(超过线程最大容量 maximum 并且 workQueue 已经被排满了)的处理策略，
     * - AbortPolicy：丢弃任务并抛出RejectedExecutionException异常
     * - DiscardPolicy：丢弃任务，但是不抛出异常。
     * - DiscardOldestPolicy：丢弃队列最前面的任务，然后重新提交被拒绝的任务
     * - CallerRunsPolicy：由调用线程（提交任务的线程）处理该任务
     */
    @Value("${thread.pool.executor.rejectedExecutionHandler}")
    private String rejectedExecutionHandler = "java.util.concurrent.ThreadPoolExecutor$AbortPolicy";

    /**
     * 非核心线程 闲置时的超时时长。超过该时长，非核心线程就会被回收。若线程池通设置
     * 核心线程也允许 timeOut，即 allowCoreThreadTimeOut 为 true，则该时长
     * 同样会作用于核心线程，在超过aliveTime 时，核心线程也会被回收，AsyncTask
     * 配置的线程池就是这样设置的。
     */
    @Value("${thread.pool.executor.keepAliveSeconds}")
    private Integer keepAliveSeconds = 60;

    public ThreadPoolConfig() {
        log.info("该台服务器的CPU核心数为{}", CPU_NUM);
        this.corePoolSize = CPU_NUM + 1;
        this.maxPoolSize = 2 * CPU_NUM;
    }

    static {
        CPU_NUM = Runtime.getRuntime().availableProcessors();
    }

}
